package com.ctrip.coverage.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ctrip.coverage.model.dto.CoverageDto;
import com.ctrip.coverage.model.dto.TfsScanDto;
import com.ctrip.coverage.model.entity.NetCoverageClassEntity;
import com.ctrip.coverage.model.entity.NetCoverageEntity;
import com.ctrip.coverage.model.entity.NetCoverageLinesEntity;
import com.ctrip.coverage.model.entity.NetCoverageMergeEntity;
import com.ctrip.coverage.model.entity.NetCoverageMethodEntity;
import com.ctrip.coverage.model.entity.NetCoverageModuleEntity;
import com.ctrip.coverage.model.entity.NetCoverageNamespaceTableEntity;
import com.ctrip.coverage.model.entity.SourceFileNamesEntity;
import com.ctrip.coverage.model.entity.TfsDifferentFileEntity;
import com.ctrip.coverage.model.entity.TfsFolderEntity;
import com.ctrip.coverage.model.entity.TfsScanEntity;
import com.ctrip.coverage.orm.dao.BaseDaoI;
import com.ctrip.coverage.orm.ibaits.dao.NetCoverageLinesMybaitisDaoI;
import com.ctrip.coverage.utils.beans.Class;
import com.ctrip.coverage.utils.beans.Lines;
import com.ctrip.coverage.utils.beans.Method;
import com.ctrip.coverage.utils.beans.Module;
import com.ctrip.coverage.utils.beans.NamespaceTable;
import com.ctrip.coverage.utils.beans.NetCoverage;
import com.ctrip.coverage.utils.beans.SourceFileNames;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;

/**
 * @author sunmx
 */
@Service("netCodeCoverageService")
public class NetCodeCoverageService {
	@Autowired
	BaseDaoI<NetCoverageEntity> netCoverageEntityDao;
	@Autowired
	BaseDaoI<NetCoverageModuleEntity> netCoverageModuleDao;
	@Autowired
	BaseDaoI<NetCoverageNamespaceTableEntity> netCoverageNamespaceTableDao;
	@Autowired
	BaseDaoI<NetCoverageClassEntity> netCoverageClassDao;
	@Autowired
	BaseDaoI<NetCoverageMethodEntity> netCoverageMethodDao;
	@Autowired
	BaseDaoI<NetCoverageLinesEntity> netCoverageLinesDao;
	@Autowired
	BaseDaoI<NetCoverageMergeEntity> netCoverageMergeDao;
	@Inject
	NetCoverageLinesMybaitisDaoI<NetCoverageLinesEntity> netCoverageLinesMybaitisDao;
	@Autowired
	BaseDaoI<SourceFileNamesEntity> sourceFileNamesDao;
	@Autowired
	BaseDaoI<TfsFolderEntity> tfsFolderDao;
	@Autowired
	BaseDaoI<TfsScanEntity> tfsScanDao;
	@Autowired
	BaseDaoI<TfsDifferentFileEntity> tfsDifferentFileDao;
	@Autowired
	TfsService tfsService;

	private static final Logger logger = Logger.getLogger(NetCodeCoverageService.class);
	XStream xstream = new XStream(new StaxDriver());

	public NetCodeCoverageService() {
		xstream.processAnnotations(NetCoverage.class);
		xstream.processAnnotations(Module.class);
		xstream.processAnnotations(NamespaceTable.class);
		//add by mcc
		xstream.processAnnotations(Class.class);
		xstream.processAnnotations(Method.class);
		xstream.processAnnotations(Lines.class);
		//end
		xstream.ignoreUnknownElements();
	}

	@Transactional
	public void addNetCoverageRecord(CoverageDto coverageDto) throws Exception {
		logger.info("addNetCoverageRecord");
		TfsFolderEntity tfsFolder = tfsFolderDao.get(TfsFolderEntity.class, coverageDto.getTfsFolderId());
		NetCoverage thecoverage = (NetCoverage) xstream.fromXML(coverageDto.getFile());
		NetCoverageEntity coverage = new NetCoverageEntity();

		int LinesCovered = 0;
		int LinesPartiallyCovered = 0;
		int LinesNotCovered = 0;
		int BlocksCovered = 0;
		int BlocksNotCovered = 0;
		BeanUtils.copyProperties(coverage, thecoverage);

		List<NetCoverageModuleEntity> modulelist = new ArrayList<NetCoverageModuleEntity>();
		for (Module module : thecoverage.getModulelist()) {
			NetCoverageModuleEntity coveragemodule = new NetCoverageModuleEntity();
			BeanUtils.copyProperties(coveragemodule, module);
			List<NetCoverageNamespaceTableEntity> spacelist = new ArrayList<NetCoverageNamespaceTableEntity>();
			for (NamespaceTable space : module.getNamespaceTableList()) {
				NetCoverageNamespaceTableEntity coveragenamespace = new NetCoverageNamespaceTableEntity();
				BeanUtils.copyProperties(coveragenamespace, space);
				List<NetCoverageClassEntity> classeslist = new ArrayList<NetCoverageClassEntity>();
				for (Class class1 : space.getClassList()) {
					NetCoverageClassEntity coverageClass = new NetCoverageClassEntity();
					BeanUtils.copyProperties(coverageClass, class1);
					List<NetCoverageMethodEntity> methodlist = new ArrayList<NetCoverageMethodEntity>();
					for (Method method : class1.getMethodList()) {
						NetCoverageMethodEntity coverageMethod = new NetCoverageMethodEntity();
						BeanUtils.copyProperties(coverageMethod, method);
						List<NetCoverageLinesEntity> lineslist = new ArrayList<NetCoverageLinesEntity>();
						if (null != method.getLinesList()) {
							for (Lines lines : method.getLinesList()) {
								NetCoverageLinesEntity coverageLines = new NetCoverageLinesEntity();
								BeanUtils.copyProperties(coverageLines, lines);
								lineslist.add(coverageLines);
							}
						}
						coverageMethod.setLinesList(lineslist);
						methodlist.add(coverageMethod);
					}
					coverageClass.setMethodList(methodlist);
					classeslist.add(coverageClass);
				}
				coveragenamespace.setClassList(classeslist);
				spacelist.add(coveragenamespace);
			}
			coveragemodule.setNamespaceTableList(spacelist);
			modulelist.add(coveragemodule);
			LinesCovered += coveragemodule.getLinesCovered();
			LinesPartiallyCovered += coveragemodule.getLinesPartiallyCovered();
			LinesNotCovered += coveragemodule.getLinesNotCovered();
			BlocksCovered += coveragemodule.getBlocksCovered();
			BlocksNotCovered += coveragemodule.getBlocksNotCovered();
		}

		List<SourceFileNamesEntity> sourceFileNamesList = new ArrayList<SourceFileNamesEntity>();
		for (SourceFileNames sourceFileNames : thecoverage.getSourceFileNamesList()) {
			SourceFileNamesEntity sourceFileNamesEntity = new SourceFileNamesEntity();
			BeanUtils.copyProperties(sourceFileNamesEntity, sourceFileNames);
			sourceFileNamesList.add(sourceFileNamesEntity);

		}

		coverage.setModulelist(modulelist);
		coverage.setSourceFileNamesList(sourceFileNamesList);
		coverage.setDescription(coverageDto.getDescription());
		coverage.setTfsFolder(tfsFolder);
		coverage.setUploadTime(new Date());
		coverage.setVersion(coverageDto.getVersion());

		coverage.setLinesCovered(LinesCovered);
		coverage.setLinesNotCovered(LinesNotCovered);
		coverage.setLinesPartiallyCovered(LinesPartiallyCovered);
		coverage.setBlocksCovered(BlocksCovered);
		coverage.setBlocksNotCovered(BlocksNotCovered);

		//级联保存
		for (NetCoverageModuleEntity module : coverage.getModulelist()) {
			module.setNetCoverage(coverage);
			for (NetCoverageNamespaceTableEntity namespace : module.getNamespaceTableList()) {
				namespace.setNetCoverageModule(module);
				for (NetCoverageClassEntity class1 : namespace.getClassList()) {
					class1.setNetCoverageNamespaceTable(namespace);
					for (NetCoverageMethodEntity method : class1.getMethodList()) {
						method.setNetCoverageClass(class1);
						for (NetCoverageLinesEntity lines : method.getLinesList()) {
							lines.setNetCoverageMethod(method);
						}
					}
				}
			}
		}

		for (SourceFileNamesEntity sourceFileNamesEntity : coverage.getSourceFileNamesList()) {
			sourceFileNamesEntity.setNetCoverage(coverage);
		}

		netCoverageEntityDao.save(coverage);

	}

	@Transactional
	public void deleteNetCoverage(Collection<NetCoverageEntity> netCoverageEntityCollection) {
		for (NetCoverageEntity netCoverageEntity : netCoverageEntityCollection) {
			logger.info("deleteNetCoverage=" + netCoverageEntity.getId());
			netCoverageEntityDao.delete(netCoverageEntity);
		}
	}

	@Transactional
	public void merageSameVersion(NetCoverageEntity startCoverage, NetCoverageEntity endCoverage) {
		//相同版本合并
		List<NetCoverageLinesEntity> startLineList = netCoverageLinesMybaitisDao.findLineByCoverageId(startCoverage.getId());
		List<NetCoverageLinesEntity> endLineList = netCoverageLinesMybaitisDao.findLineByCoverageId(endCoverage.getId());

		for (NetCoverageLinesEntity startLine : startLineList) {
			for (NetCoverageLinesEntity endLine : endLineList) {
				if (startLine.getSourceFileID() == endLine.getSourceFileID() && startLine.getLnStart() == endLine.getLnStart() && startLine.getLnEnd() == endLine.getLnEnd()
						&& startLine.getCoverage() != endLine.getCoverage() && endLine.getCoverage() != 0) {
					endLine.setCoverage(0);
					netCoverageLinesDao.update(endLine);
				}
			}
		}
		//覆盖数更新

		int cLineCoverage = 0;
		int cLineNoCoverage = 0;
		int cLinePaCoverage = 0;
		List<NetCoverageModuleEntity> moduleList = new ArrayList<NetCoverageModuleEntity>();
		for (NetCoverageModuleEntity module : endCoverage.getModulelist()) {
			int moduleLineCoverage = 0;
			int moduleLineNoCoverage = 0;
			int moduleLinePaCoverage = 0;
			List<NetCoverageNamespaceTableEntity> namespaceList = new ArrayList<NetCoverageNamespaceTableEntity>();
			for (NetCoverageNamespaceTableEntity namespace : module.getNamespaceTableList()) {
				int namespaceLineCoverage = 0;
				int namespaceLineNoCoverage = 0;
				int namespaceLinePaCoverage = 0;
				List<NetCoverageClassEntity> classList = new ArrayList<NetCoverageClassEntity>();
				for (NetCoverageClassEntity class1 : namespace.getClassList()) {
					int classLineCoverage = 0;
					int classLineNoCoverage = 0;
					int classLinePaCoverage = 0;
					List<NetCoverageMethodEntity> methodList = new ArrayList<NetCoverageMethodEntity>();
					for (NetCoverageMethodEntity method : class1.getMethodList()) {
						int methodLineCoverage = 0;
						int methodLineNoCoverage = 0;
						int methodLinePaCoverage = 0;

						for (NetCoverageLinesEntity lines : method.getLinesList()) {
							if (lines.getCoverage() == 0) {
								methodLineCoverage++;
							} else if (lines.getCoverage() == 2) {
								methodLineNoCoverage++;
							} else {
								methodLinePaCoverage++;
							}
						}
						method.setLinesCovered(methodLineCoverage);
						method.setLinesPartiallyCovered(methodLinePaCoverage);
						method.setLinesNotCovered(methodLineNoCoverage);
						method.setNetCoverageClass(class1);
						methodList.add(method);
						classLineCoverage = classLineCoverage + methodLineCoverage;
						classLineNoCoverage = classLineNoCoverage + methodLineNoCoverage;
						classLinePaCoverage = classLinePaCoverage + methodLinePaCoverage;
					}
					class1.setLinesCovered(classLineCoverage);
					class1.setLinesNotCovered(classLineNoCoverage);
					class1.setLinesPartiallyCovered(classLinePaCoverage);
					class1.setMethodList(methodList);
					class1.setNetCoverageNamespaceTable(namespace);
					classList.add(class1);
					namespaceLineCoverage = namespaceLineCoverage + classLineCoverage;
					namespaceLineNoCoverage = namespaceLineNoCoverage + classLineNoCoverage;
					namespaceLinePaCoverage = namespaceLinePaCoverage + classLinePaCoverage;

				}
				namespace.setLinesCovered(namespaceLineCoverage);
				namespace.setLinesNotCovered(namespaceLineNoCoverage);
				namespace.setLinesPartiallyCovered(namespaceLinePaCoverage);
				namespace.setClassList(classList);
				namespace.setNetCoverageModule(module);
				namespaceList.add(namespace);
				moduleLineCoverage = moduleLineCoverage + namespaceLineCoverage;
				moduleLineNoCoverage = moduleLineNoCoverage + namespaceLineNoCoverage;
				moduleLinePaCoverage = moduleLinePaCoverage + namespaceLinePaCoverage;

			}
			module.setLinesCovered(moduleLineCoverage);
			module.setLinesNotCovered(moduleLineNoCoverage);
			module.setLinesPartiallyCovered(moduleLinePaCoverage);
			module.setNamespaceTableList(namespaceList);
			moduleList.add(module);
			module.setNetCoverage(endCoverage);
			cLineCoverage = cLineCoverage + moduleLineCoverage;
			cLineNoCoverage = cLineNoCoverage + moduleLineNoCoverage;
			cLinePaCoverage = cLinePaCoverage + moduleLinePaCoverage;

		}
		endCoverage.setLinesCovered(cLineCoverage);
		endCoverage.setLinesNotCovered(cLineNoCoverage);
		endCoverage.setLinesPartiallyCovered(cLinePaCoverage);
		endCoverage.setModulelist(moduleList);
		if (null != endCoverage.getMeragePath()) {
			boolean isCoverage = false;
			String a[] = endCoverage.getMeragePath().split(",");
			for (int i = 0; i < a.length; i++) {
				String b[] = a[i].split("->");
				if (b[0].equals(String.valueOf(startCoverage.getId())) && b[1].equals(String.valueOf(endCoverage.getId()))) {
					isCoverage = true;
				}
			}
			if (isCoverage == false) {
				endCoverage.setMeragePath("," + startCoverage.getId() + "->" + endCoverage.getId());
			}
		} else {
			endCoverage.setMeragePath(startCoverage.getId() + "->" + endCoverage.getId());
		}

	}

	@Transactional
	public void meragDiffVersion(NetCoverageEntity startCoverage, NetCoverageEntity endCoverage, TfsFolderEntity tfsFolderEntity) throws Exception {
		//不同版本合并
		List<SourceFileNamesEntity> endSourceFilesList = sourceFileNamesDao.find("from SourceFileNamesEntity where netCoverage.id=?", endCoverage.getId());
		TfsScanEntity tfsScanEntity = tfsScanDao.get(" from TfsScanEntity where startVersion=" + startCoverage.getVersion() + "and endVersion=" + endCoverage.getVersion()
				+ "and tfsFolder.id=" + tfsFolderEntity.getId());
		if (null == tfsScanEntity) {
			TfsScanDto tfsscanDto = new TfsScanDto();
			tfsscanDto.setStartVersion(startCoverage.getVersion());
			tfsscanDto.setEndVersion(endCoverage.getVersion());
			tfsService.scanTfs(tfsFolderEntity, tfsscanDto);
			tfsScanEntity = tfsScanDao.get(" from TfsScanEntity where startVersion=" + startCoverage.getVersion() + "and endVersion=" + endCoverage.getVersion()
					+ "and tfsFolder.id=" + tfsFolderEntity.getId());
		}
		List<TfsDifferentFileEntity> tfsDifferentFileList = tfsDifferentFileDao.find("from TfsDifferentFileEntity where tfsScan.id=?", tfsScanEntity.getId());

		for (int j = 0; j < endSourceFilesList.size(); j++) {
			String b = endSourceFilesList.get(j).getSourceFileName();
			for (int i = 0; i < tfsDifferentFileList.size(); i++) {
				String a = tfsDifferentFileList.get(i).getPath();
				if (a.startsWith("$")) {
					a = a.replaceAll("/", "\\\\");
				}
				String c[] = a.split("\\\\");
				String d[] = b.split("\\\\");
				a = c[c.length - 2].toString() + "\\" + c[c.length - 1].toString();
				b = d[d.length - 2].toString() + "\\" + d[d.length - 1].toString();
				if (a.equals(b)) {
					endSourceFilesList.remove(j);
					break;
				}
			}
		}
		List<NetCoverageLinesEntity> startLineList = null;
		List<NetCoverageLinesEntity> endLineList = null;
		for (SourceFileNamesEntity sourceFileNamesEntity : endSourceFilesList) {
			startLineList = netCoverageLinesMybaitisDao.findLineBySourceId(startCoverage.getId(), sourceFileNamesEntity.getSourceFileID());
			endLineList = netCoverageLinesMybaitisDao.findLineBySourceId(endCoverage.getId(), sourceFileNamesEntity.getSourceFileID());
			for (NetCoverageLinesEntity startLine : startLineList) {
				for (NetCoverageLinesEntity endLine : endLineList) {
					if (startLine.getSourceFileID() == endLine.getSourceFileID() && startLine.getLnStart() == endLine.getLnStart() && startLine.getLnEnd() == endLine.getLnEnd()
							&& startLine.getCoverage() != endLine.getCoverage() && endLine.getCoverage() != 0) {
						endLine.setCoverage(0);
						netCoverageLinesDao.update(endLine);
					}
				}
			}
		}

		int cLineCoverage = 0;
		int cLineNoCoverage = 0;
		int cLinePaCoverage = 0;
		List<NetCoverageModuleEntity> moduleList = new ArrayList<NetCoverageModuleEntity>();
		for (NetCoverageModuleEntity module : endCoverage.getModulelist()) {
			int moduleLineCoverage = 0;
			int moduleLineNoCoverage = 0;
			int moduleLinePaCoverage = 0;
			List<NetCoverageNamespaceTableEntity> namespaceList = new ArrayList<NetCoverageNamespaceTableEntity>();
			for (NetCoverageNamespaceTableEntity namespace : module.getNamespaceTableList()) {
				int namespaceLineCoverage = 0;
				int namespaceLineNoCoverage = 0;
				int namespaceLinePaCoverage = 0;
				List<NetCoverageClassEntity> classList = new ArrayList<NetCoverageClassEntity>();
				for (NetCoverageClassEntity class1 : namespace.getClassList()) {
					int classLineCoverage = 0;
					int classLineNoCoverage = 0;
					int classLinePaCoverage = 0;
					List<NetCoverageMethodEntity> methodList = new ArrayList<NetCoverageMethodEntity>();
					for (NetCoverageMethodEntity method : class1.getMethodList()) {
						int methodLineCoverage = 0;
						int methodLineNoCoverage = 0;
						int methodLinePaCoverage = 0;

						for (NetCoverageLinesEntity lines : method.getLinesList()) {
							if (lines.getCoverage() == 0) {
								methodLineCoverage++;
							} else if (lines.getCoverage() == 2) {
								methodLineNoCoverage++;
							} else {
								methodLinePaCoverage++;
							}
						}
						method.setLinesCovered(methodLineCoverage);
						method.setLinesPartiallyCovered(methodLinePaCoverage);
						method.setLinesNotCovered(methodLineNoCoverage);
						method.setNetCoverageClass(class1);
						methodList.add(method);
						classLineCoverage = classLineCoverage + methodLineCoverage;
						classLineNoCoverage = classLineNoCoverage + methodLineNoCoverage;
						classLinePaCoverage = classLinePaCoverage + methodLinePaCoverage;
					}
					class1.setLinesCovered(classLineCoverage);
					class1.setLinesNotCovered(classLineNoCoverage);
					class1.setLinesPartiallyCovered(classLinePaCoverage);
					class1.setMethodList(methodList);
					class1.setNetCoverageNamespaceTable(namespace);
					classList.add(class1);
					namespaceLineCoverage = namespaceLineCoverage + classLineCoverage;
					namespaceLineNoCoverage = namespaceLineNoCoverage + classLineNoCoverage;
					namespaceLinePaCoverage = namespaceLinePaCoverage + classLinePaCoverage;

				}
				namespace.setLinesCovered(namespaceLineCoverage);
				namespace.setLinesNotCovered(namespaceLineNoCoverage);
				namespace.setLinesPartiallyCovered(namespaceLinePaCoverage);
				namespace.setClassList(classList);
				namespace.setNetCoverageModule(module);
				namespaceList.add(namespace);
				moduleLineCoverage = moduleLineCoverage + namespaceLineCoverage;
				moduleLineNoCoverage = moduleLineNoCoverage + namespaceLineNoCoverage;
				moduleLinePaCoverage = moduleLinePaCoverage + namespaceLinePaCoverage;

			}
			module.setLinesCovered(moduleLineCoverage);
			module.setLinesNotCovered(moduleLineNoCoverage);
			module.setLinesPartiallyCovered(moduleLinePaCoverage);
			module.setNamespaceTableList(namespaceList);
			moduleList.add(module);
			module.setNetCoverage(endCoverage);
			cLineCoverage = cLineCoverage + moduleLineCoverage;
			cLineNoCoverage = cLineNoCoverage + moduleLineNoCoverage;
			cLinePaCoverage = cLinePaCoverage + moduleLinePaCoverage;

		}

		endCoverage.setLinesCovered(cLineCoverage);
		endCoverage.setLinesNotCovered(cLineNoCoverage);
		endCoverage.setLinesPartiallyCovered(cLinePaCoverage);
		endCoverage.setModulelist(moduleList);

		if (null != endCoverage.getMeragePath()) {
			boolean isCoverage = false;
			String a[] = endCoverage.getMeragePath().split(",");
			for (int i = 0; i < a.length; i++) {
				String b[] = a[i].split("->");
				if (b[0].equals(String.valueOf(startCoverage.getId())) && b[1].equals(String.valueOf(endCoverage.getId()))) {
					isCoverage = true;
				}
			}
			if (isCoverage == false) {
				endCoverage.setMeragePath("," + startCoverage.getId() + "->" + endCoverage.getId());
			}
		} else {
			endCoverage.setMeragePath(startCoverage.getId() + "->" + endCoverage.getId());
		}

	}

	@Transactional
	public void merageSolution(List<TfsFolderEntity> tfsFolderList) {
		tfsScanDao.executeHql("delete from NetCoverageEntity where tfsFolder.id=" + tfsFolderList.get(0).getParentId());
		TfsFolderEntity tfsFolderParent = tfsFolderDao.get(" from TfsFolderEntity where id=" + tfsFolderList.get(0).getParentId());
		initVersionCoverage(tfsFolderList.get(tfsFolderList.size() - 1), tfsFolderParent);
		for (int i = 0; i < tfsFolderList.size() - 1; i++) {
			merageSolutionTfs(tfsFolderList.get(tfsFolderList.size() - 2 - i), tfsFolderParent, tfsFolderList.get(tfsFolderList.size() - 1));
		}
	}

	//将最新Solution作为版本初始化覆盖率，后面的Solution将都被合并到此覆盖率中
	public void initVersionCoverage(TfsFolderEntity tfsFolderNewest, TfsFolderEntity tfsFolderParent) {

		List<NetCoverageEntity> netCoverageList = netCoverageEntityDao.find("from NetCoverageEntity where tfsFolder.id=" + tfsFolderNewest.getId()
				+ "order by  version desc,id DESC");
		tfsFolderParent.setServerPath(tfsFolderNewest.getServerPath());
		NetCoverageEntity netCoverage = netCoverageList.get(0);

		NetCoverageEntity netCoverageNew = new NetCoverageEntity();

		try {
			BeanUtils.copyProperties(netCoverageNew, netCoverage);

			List<NetCoverageModuleEntity> modulelist = new ArrayList<NetCoverageModuleEntity>();
			for (NetCoverageModuleEntity module : netCoverage.getModulelist()) {
				NetCoverageModuleEntity coveragemodule = new NetCoverageModuleEntity();
				BeanUtils.copyProperties(coveragemodule, module);
				coveragemodule.setId(null);
				coveragemodule.setNetCoverage(netCoverageNew);
				List<NetCoverageNamespaceTableEntity> spacelist = new ArrayList<NetCoverageNamespaceTableEntity>();
				for (NetCoverageNamespaceTableEntity space : module.getNamespaceTableList()) {
					NetCoverageNamespaceTableEntity coveragenamespace = new NetCoverageNamespaceTableEntity();
					BeanUtils.copyProperties(coveragenamespace, space);
					coveragenamespace.setId(null);
					coveragenamespace.setNetCoverageModule(coveragemodule);
					List<NetCoverageClassEntity> classeslist = new ArrayList<NetCoverageClassEntity>();
					for (NetCoverageClassEntity class1 : space.getClassList()) {
						NetCoverageClassEntity coverageClass = new NetCoverageClassEntity();
						BeanUtils.copyProperties(coverageClass, class1);
						coverageClass.setId(null);
						coverageClass.setNetCoverageNamespaceTable(coveragenamespace);
						List<NetCoverageMethodEntity> methodlist = new ArrayList<NetCoverageMethodEntity>();
						for (NetCoverageMethodEntity method : class1.getMethodList()) {
							NetCoverageMethodEntity coverageMethod = new NetCoverageMethodEntity();
							BeanUtils.copyProperties(coverageMethod, method);
							coverageMethod.setId(null);
							coverageMethod.setNetCoverageClass(coverageClass);
							List<NetCoverageLinesEntity> lineslist = new ArrayList<NetCoverageLinesEntity>();
							for (NetCoverageLinesEntity lines : method.getLinesList()) {
								NetCoverageLinesEntity coverageLines = new NetCoverageLinesEntity();
								BeanUtils.copyProperties(coverageLines, lines);
								coverageLines.setId(null);
								coverageLines.setNetCoverageMethod(coverageMethod);
								lineslist.add(coverageLines);
							}
							coverageMethod.setLinesList(lineslist);
							methodlist.add(coverageMethod);
						}
						coverageClass.setMethodList(methodlist);
						classeslist.add(coverageClass);
					}
					coveragenamespace.setClassList(classeslist);
					spacelist.add(coveragenamespace);
				}
				coveragemodule.setNamespaceTableList(spacelist);
				modulelist.add(coveragemodule);
			}

			List<SourceFileNamesEntity> sourceFileNamesList = new ArrayList<SourceFileNamesEntity>();
			for (SourceFileNamesEntity sourceFileNames : netCoverage.getSourceFileNamesList()) {
				SourceFileNamesEntity sourceFileNamesEntity = new SourceFileNamesEntity();
				BeanUtils.copyProperties(sourceFileNamesEntity, sourceFileNames);
				sourceFileNamesEntity.setId(null);
				sourceFileNamesEntity.setNetCoverage(netCoverageNew);
				sourceFileNamesList.add(sourceFileNamesEntity);

			}
			netCoverageNew.setTfsFolder(tfsFolderParent);
			netCoverageNew.setSourceFileNamesList(sourceFileNamesList);
			netCoverageNew.setModulelist(modulelist);
			netCoverageNew.setId(null);
			netCoverageNew.setVersion(tfsFolderNewest.getName());
			netCoverageNew.setUploadTime(new Date());
			netCoverageEntityDao.save(netCoverageNew);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//具体扫描合并
	@Transactional
	public void merageSolutionTfs(TfsFolderEntity tfsFolderStart, TfsFolderEntity tfsFolderParent, TfsFolderEntity tfsFolderEnd) {
		NetCoverageEntity netCoverageParent = netCoverageEntityDao.get(" from NetCoverageEntity where tfsFolder.id=" + tfsFolderParent.getId());

		List<NetCoverageEntity> netCoverageList = netCoverageEntityDao.find("from NetCoverageEntity where tfsFolder.id=" + tfsFolderStart.getId()
				+ "order by  version desc,id DESC");

		TfsScanEntity tfsScanEntity = tfsScanDao.get("from TfsScanEntity where startVersion='" + tfsFolderStart.getName() + "' and endVersion='" + netCoverageParent.getVersion()
				+ "' and tfsFolder.id=" + tfsFolderParent.getId());
		if (null == tfsScanEntity) {
			try {
				tfsService.tfsScanSolution(tfsFolderStart, tfsFolderEnd);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			merageDiffSolution(netCoverageList.get(0), netCoverageParent, tfsScanEntity);
		}
	}

	public void merageDiffSolution(NetCoverageEntity startCoverage, NetCoverageEntity endCoverage, TfsScanEntity tfsScanEntity) {
		List<SourceFileNamesEntity> endSourceFilesList = sourceFileNamesDao.find("from SourceFileNamesEntity where netCoverage.id=?", endCoverage.getId());
		List<TfsDifferentFileEntity> tfsDifferentFileList = tfsDifferentFileDao.find("from TfsDifferentFileEntity where tfsScan.id=?", tfsScanEntity.getId());
		if (tfsDifferentFileList.size() > 0) {
			for (int j = 0; j < endSourceFilesList.size(); j++) {
				String b = endSourceFilesList.get(j).getSourceFileName();
				for (int i = 0; i < tfsDifferentFileList.size(); i++) {
					String a = tfsDifferentFileList.get(i).getPath();

					String c[] = a.split("\\\\");
					String d[] = b.split("\\\\");
					a = c[c.length - 2].toString() + "\\" + c[c.length - 1].toString();
					b = d[d.length - 2].toString() + "\\" + d[d.length - 1].toString();
					if (a.equals(b)) {
						endSourceFilesList.remove(j);
						break;
					}
				}
			}
		}
		List<NetCoverageLinesEntity> startLineList = null;
		List<NetCoverageLinesEntity> endLineList = null;
		for (SourceFileNamesEntity sourceFileNamesEntity : endSourceFilesList) {
			startLineList = netCoverageLinesMybaitisDao.findLineBySourceId(startCoverage.getId(), sourceFileNamesEntity.getSourceFileID());
			endLineList = netCoverageLinesMybaitisDao.findLineBySourceId(endCoverage.getId(), sourceFileNamesEntity.getSourceFileID());
			for (NetCoverageLinesEntity startLine : startLineList) {
				for (NetCoverageLinesEntity endLine : endLineList) {
					if (startLine.getSourceFileID() == endLine.getSourceFileID() && startLine.getLnStart() == endLine.getLnStart() && startLine.getLnEnd() == endLine.getLnEnd()
							&& startLine.getCoverage() != endLine.getCoverage() && endLine.getCoverage() != 0) {
						endLine.setCoverage(0);
						netCoverageLinesDao.merge(endLine);
					}
				}
			}
		}

		int cLineCoverage = 0;
		int cLineNoCoverage = 0;
		int cLinePaCoverage = 0;
		List<NetCoverageModuleEntity> moduleList = new ArrayList<NetCoverageModuleEntity>();
		for (NetCoverageModuleEntity module : endCoverage.getModulelist()) {
			int moduleLineCoverage = 0;
			int moduleLineNoCoverage = 0;
			int moduleLinePaCoverage = 0;
			List<NetCoverageNamespaceTableEntity> namespaceList = new ArrayList<NetCoverageNamespaceTableEntity>();
			for (NetCoverageNamespaceTableEntity namespace : module.getNamespaceTableList()) {
				int namespaceLineCoverage = 0;
				int namespaceLineNoCoverage = 0;
				int namespaceLinePaCoverage = 0;
				List<NetCoverageClassEntity> classList = new ArrayList<NetCoverageClassEntity>();
				for (NetCoverageClassEntity class1 : namespace.getClassList()) {
					int classLineCoverage = 0;
					int classLineNoCoverage = 0;
					int classLinePaCoverage = 0;
					List<NetCoverageMethodEntity> methodList = new ArrayList<NetCoverageMethodEntity>();
					for (NetCoverageMethodEntity method : class1.getMethodList()) {
						int methodLineCoverage = 0;
						int methodLineNoCoverage = 0;
						int methodLinePaCoverage = 0;

						for (NetCoverageLinesEntity lines : method.getLinesList()) {
							if (lines.getCoverage() == 0) {
								methodLineCoverage++;
							} else if (lines.getCoverage() == 2) {
								methodLineNoCoverage++;
							} else {
								methodLinePaCoverage++;
							}
						}
						method.setLinesCovered(methodLineCoverage);
						method.setLinesPartiallyCovered(methodLinePaCoverage);
						method.setLinesNotCovered(methodLineNoCoverage);
						method.setNetCoverageClass(class1);
						methodList.add(method);
						classLineCoverage = classLineCoverage + methodLineCoverage;
						classLineNoCoverage = classLineNoCoverage + methodLineNoCoverage;
						classLinePaCoverage = classLinePaCoverage + methodLinePaCoverage;
					}
					class1.setLinesCovered(classLineCoverage);
					class1.setLinesNotCovered(classLineNoCoverage);
					class1.setLinesPartiallyCovered(classLinePaCoverage);
					class1.setMethodList(methodList);
					class1.setNetCoverageNamespaceTable(namespace);
					classList.add(class1);
					namespaceLineCoverage = namespaceLineCoverage + classLineCoverage;
					namespaceLineNoCoverage = namespaceLineNoCoverage + classLineNoCoverage;
					namespaceLinePaCoverage = namespaceLinePaCoverage + classLinePaCoverage;

				}
				namespace.setLinesCovered(namespaceLineCoverage);
				namespace.setLinesNotCovered(namespaceLineNoCoverage);
				namespace.setLinesPartiallyCovered(namespaceLinePaCoverage);
				namespace.setClassList(classList);
				namespace.setNetCoverageModule(module);
				namespaceList.add(namespace);
				moduleLineCoverage = moduleLineCoverage + namespaceLineCoverage;
				moduleLineNoCoverage = moduleLineNoCoverage + namespaceLineNoCoverage;
				moduleLinePaCoverage = moduleLinePaCoverage + namespaceLinePaCoverage;

			}
			module.setLinesCovered(moduleLineCoverage);
			module.setLinesNotCovered(moduleLineNoCoverage);
			module.setLinesPartiallyCovered(moduleLinePaCoverage);
			module.setNamespaceTableList(namespaceList);
			moduleList.add(module);
			module.setNetCoverage(endCoverage);
			cLineCoverage = cLineCoverage + moduleLineCoverage;
			cLineNoCoverage = cLineNoCoverage + moduleLineNoCoverage;
			cLinePaCoverage = cLinePaCoverage + moduleLinePaCoverage;

		}
		endCoverage.setLinesCovered(cLineCoverage);
		endCoverage.setLinesNotCovered(cLineNoCoverage);
		endCoverage.setLinesPartiallyCovered(cLinePaCoverage);
		endCoverage.setModulelist(moduleList);
		if (null != endCoverage.getMeragePath()) {
			boolean isCoverage = false;
			String a[] = endCoverage.getMeragePath().split(",");
			for (int i = 0; i < a.length; i++) {
				String b[] = a[i].split("->");
				if (b[0].equals(String.valueOf(startCoverage.getId())) && b[1].equals(String.valueOf(endCoverage.getId()))) {
					isCoverage = true;
				}
			}
			if (isCoverage == false) {
				endCoverage.setMeragePath("," + startCoverage.getId() + "->" + endCoverage.getId());
			}
		} else {
			endCoverage.setMeragePath(startCoverage.getId() + "->" + endCoverage.getId());
		}

	}

}